﻿<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport"
          content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
    <title>Tools-07CesiumNavigation</title>
    <script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
    <script type="text/javascript" src="js/jquery.contextMenu.min.js"></script>
    <script src="./js/Cesium.js"></script>
    <script src="./js/viewerCesiumNavigationMixin.min.js"></script>
    <script type="text/javascript" src="js/require.js"></script>

    <link rel="stylesheet" type="text/css" href="css/base.css"/>
    <script type="text/javascript" src="js/temp/common.js"></script>
    <script type="text/javascript" src="js/temp/quick_links.js"></script>

    <link rel="stylesheet" href="css/style.css"/>

    <link rel="stylesheet" href="bootstrap/css/bootstrap.css"/>
    <link rel="stylesheet" href="css/contextMenu.css"/>
    <script type="text/javascript" src="bootstrap/js/bootstrap.js"></script>
    <script type="text/javascript" src="js/Sandcastle-header.js"></script>
    <script src="js/temp/parabola.js"></script>

    <style>
        @import url(./css/widgets.css);
        @import url(./css/bucket.css);
    </style>
</head>
<body>
<input id="lng_none" type="text" style="display: none;"/>
<input id="lat_none" type="text" style="display: none;"/>
<input id="hig_none" type="text" style="display: none;"/>

<div id="cesiumContainer">
    <div id="creditContainer"></div>
</div>
<div id="loadingOverlay"><h1>Loading...</h1></div>
<div id="toolbar"></div>

<div id="wrapper">
    <!-- Sidebar -->
    <nav class="navbar navbar-inverse navbar-fixed-top" id="sidebar-wrapper" role="navigation">
        <ul class="nav sidebar-nav">
            <li class="sidebar-brand">
                <a href="#">
                    标题
                </a>
            </li>
        </ul>
    </nav>
    <!-- /#sidebar-wrapper -->
    <button type="button" class="hamburger is-closed animated fadeInLeft" data-toggle="offcanvas">
        <span class="hamb-top"></span>
        <span class="hamb-middle"></span>
        <span class="hamb-bottom"></span>
    </button>
</div>

<!--右侧贴边导航quick_links.js控制-->
<div class="mui-mbar-tabs">

    <div class="quick_link_mian">

        <div class="quick_links_panel">
            <div id="quick_links" class="quick_links">
                <li><a href="#" class="history_list"><i class="view"></i></a>
                    <div class="mp_tooltip" style=" visibility:hidden;">状态指示<i class="icon_arrow_right_black"></i></div>
                </li>
                <li><a href="#" class="mpbtn_histroy"><i class="zuji"></i></a>
                    <div class="mp_tooltip">菜单二<i class="icon_arrow_right_black"></i></div>
                </li>
                <li><a href="#" class="mpbtn_wdsc"><i class="wdsc"></i></a>
                    <div class="mp_tooltip">菜单三<i class="icon_arrow_right_black"></i></div>
                </li>
            </div>

            <div class="quick_toggle">
                <li><a href="#none"><i class="mpbtn_qrcode"></i></a>
                    <div class="mp_qrcode" style="display:none;"><img src="images/weixin_code_145.png" width="148"
                                                                      height="175"/>
                    </div>
                </li>
                <li><a href="#top" class="return_top"><i class="top"></i></a></li>
            </div>
        </div>

        <!--弹出层-->
        <div id="quick_links_pop" class="quick_links_pop hide"></div>

    </div>

</div>

<script>
    $("#cesiumContainer").contextMenu({
        menu: [{
            text: "导弹",
            callback: function () {
                createModel('model/daodan.gltf', 'daodan');
            }
        },
            {
                text: "导弹车",
                callback: function () {
                    createModel('model/daodanche.gltf', 'daodanche')
                }
            },
            {
                text: "雷达",
                callback: function () {
                    createModel('model/leida.gltf', 'leida')
                }
            },
            {
                text: "指挥中心",
                callback: function () {
                    createModel('model/huiyishi.gltf', 'zhihuizhongxin')
                }
            },
            {
                text: "导弹井",
                callback: function () {
                    createModel('model/daodanjing.gltf', 'daodanjing')
                }
            },
            {
                text: "飞机",
                callback: function () {
                    createModel('model/CesiumAir/Cesium_Air.gltf', 'feiji')
                }
            }
        ]
    });


    // 'use strict';
    var viewer = new Cesium.Viewer('cesiumContainer', {
        // imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
        //     url: "http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
        // }),

        shouldAnimate: false,
        infoBox: false,
        selectionIndicator: false,
        shadows: false,
        geocoder: false,
        homeButton: false,
        sceneModePicker: false,
        baseLayerPicker: false,
        navigationHelpButton: false,
        // animation: false,
        // timeline: false,
        fullscreenButton: false,

        skyAtmosphere: false,
        shouldAnimate: true,
        // terrainProvider: Cesium.createWorldTerrain(),
        scene3DOnly: true,

        /*
        * 动画播放
        * */
        shouldAnimate: true
    });

    // extend our view by the cesium navigation mixin
    viewer.extend(Cesium.viewerCesiumNavigationMixin, {});
    // you can access the cesium navigation by cesiumViewer.cesiumNavigation or cesiumViewer.cesiumWidget.cesiumNavigation

    var lon = 100.980071;  //经度
    var lat = 39.770983;   // 纬度

    var scanColor = new Cesium.Color(1.0, 0.0, 0.0, 1);
    var CartographicCenter = new Cesium.Cartographic(Cesium.Math.toRadians(lon), Cesium.Math.toRadians(lat), 0);

    window.setTimeout(function () {
        AddCircleScanPostStage(viewer, CartographicCenter, 5, scanColor, 4000);
    }, 2500);


    viewer._cesiumWidget._creditContainer.style.display = "none";


    changjing(viewer);
    difang(viewer);
    wofang(viewer);

    var params = {
        // 100.980228,39.771246
        // tx: 85.079709,    //模型中心X轴坐标（经度，单位：十进制度）   
        // ty: 33.930379,     //模型中心Y轴坐标（纬度，单位：十进制度）   
        tx: 100.980228,    //模型中心X轴坐标（经度，单位：十进制度）   
        ty: 39.771246,     //模型中心Y轴坐标（纬度，单位：十进制度）   
        tz: 10,      //模型中心Z轴坐标（高程，单位：米）   
        rx: 0,     //X轴（经度）方向旋转角度（单位：度）   
        ry: 0,     //Y轴（纬度）方向旋转角度（单位：度）   
        rz: 0      //Z轴（高程）方向旋转角度（单位：度）
    };

    function update3dtilesMaxtrix(tileset) {
        //旋转
        var mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(params.rx));
        var my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(params.ry));
        var mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(params.rz));
        var rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
        var rotationY = Cesium.Matrix4.fromRotationTranslation(my);
        var rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
        //平移
        var position = Cesium.Cartesian3.fromDegrees(params.tx, params.ty, params.tz);
        var m = Cesium.Transforms.eastNorthUpToFixedFrame(position);
        //旋转、平移矩阵相乘
        Cesium.Matrix4.multiply(m, rotationX, m);
        Cesium.Matrix4.multiply(m, rotationY, m);
        Cesium.Matrix4.multiply(m, rotationZ, m);    //赋值给tileset   
        tileset._root.transform = m;
    }


    function changjing(viewer) {
        viewer.scene.globe.depthTestAgainstTerrain = true;
        var url = "model/changjing2/tileset.json";
        var tileset = new Cesium.Cesium3DTileset({url: url});

        var primitive1 = viewer.scene.primitives.add(tileset);

        primitive1.readyPromise.then(function (t) {
            var originalSphere = t.boundingSphere;
            var radius = originalSphere.radius;
            viewer.zoomTo(t, new Cesium.HeadingPitchRange(0.5, -0.5, radius * 4.0));
            //平移、贴地、旋转模型
            update3dtilesMaxtrix(tileset);

        }).otherwise(function (error) {

            var msg = JSON.stringify(error);

            console.log("msg ------------->" + msg);
        });
    }

    /**
     * 敌方导弹
     * */
    function difang(view) {
        view.scene.globe.enableLighting = true;

        let data = [];
        data[0] = [
            {longitude: 100.980228, dimension: 39.771246, height: 100, time: 6},
            {longitude: 100.980228, dimension: 39.771246, height: 90, time: 7},
            {longitude: 100.980228, dimension: 39.771246, height: 80, time: 8},
            {longitude: 100.980228, dimension: 39.771246, height: 70, time: 9},
            {longitude: 100.980228, dimension: 39.771246, height: 60, time: 10},
            {longitude: 100.980228, dimension: 39.771246, height: 50, time: 11},
            {longitude: 100.980228, dimension: 39.771246, height: 40, time: 12},
            {longitude: 100.980228, dimension: 39.771246, height: 30, time: 13},
            {longitude: 100.980228, dimension: 39.771246, height: 20, time: 14},
            {longitude: 100.980228, dimension: 39.771246, height: 10, time: 15},
            {longitude: 100.980228, dimension: 39.771246, height: 1, time: 16},
            {longitude: 100.980228, dimension: 39.771246, height: -10, time: 18},
        ];

        // 起始时间
        let start = Cesium.JulianDate.fromDate(new Date(2019, 8, 19));
        // 结束时间
        let stop = Cesium.JulianDate.addSeconds(start, 360, new Cesium.JulianDate());
        // 设置始时钟始时间
        view.clock.startTime = start.clone();
        // 设置时钟当前时间
        view.clock.currentTime = start.clone();
        // 设置始终停止时间
        view.clock.stopTime = stop.clone();
        // 时间速率，数字越大时间过的越快
        view.clock.multiplier = 10;
        // 时间轴
        view.timeline.zoomTo(start, stop);
        // 循环执行,即为2，到达终止时间，重新从起点时间开始
        view.clock.clockRange = Cesium.ClockRange.LOOP_STOP;

        // // 镜头飞跃
        // view.camera.flyTo({
        //     destination:Cesium.Cartesian3.fromDegrees(116.405419,32.073514,500000)
        // })

        for (let j = 0; j < data.length; j++) {
            let property = computeFlight(data[j]);
            // 添加模型
            let planeModel = view.entities.add({
                // 和时间轴关联
                availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
                    start: start,
                    stop: stop
                })]),
                position: property,
                // 根据所提供的速度计算模型的朝向
                orientation: new Cesium.VelocityOrientationProperty(property),
                // 模型数据
                model: {
                    uri: 'model/laixidantou.gltf',
                }
            });
        }


        /**
         * 计算飞行
         * @param source 数据坐标
         * @returns {SampledPositionProperty|*}
         */
        function computeFlight(source) {
            // 取样位置 相当于一个集合
            let property = new Cesium.SampledPositionProperty();
            console.log("computeFlight property" + property)

            for (let i = 0; i < source.length; i++) {
                let time = Cesium.JulianDate.addSeconds(start, source[i].time, new Cesium.JulianDate);
                let position = Cesium.Cartesian3.fromDegrees(source[i].longitude, source[i].dimension, source[i].height);
                // 添加位置，和时间对应
                property.addSample(time, position);
            }
            return property;
        }

    }

    /**
     * 我方导弹
     * */
    function wofang(view) {
        view.scene.globe.enableLighting = true;

        let data = [];
        data[0] = [

            {longitude: 100.980228, dimension: 39.771246, height: -10, time: 25},
            {longitude: 100.980228, dimension: 39.771246, height: 5, time: 26},
            {longitude: 100.980228, dimension: 39.771246, height: 1, time: 27},
            {longitude: 100.980228, dimension: 39.771246, height: 4, time: 28},
            {longitude: 100.980228, dimension: 39.771246, height: 6, time: 29},
            {longitude: 100.980228, dimension: 39.771246, height: 8, time: 30},
            {longitude: 100.980228, dimension: 39.771246, height: 10, time: 31},
            {longitude: 100.980228, dimension: 39.771246, height: 12, time: 32},
            {longitude: 100.980228, dimension: 39.771246, height: 20, time: 33},
            {longitude: 100.980228, dimension: 39.771246, height: 25, time: 34},
            {longitude: 100.980228, dimension: 39.771246, height: 30, time: 35},
            {longitude: 100.980228, dimension: 39.771246, height: 35, time: 36},
            {longitude: 100.980228, dimension: 39.771246, height: 40, time: 37},
            {longitude: 100.980228, dimension: 39.771246, height: 45, time: 38},
            {longitude: 100.980228, dimension: 39.771246, height: 50, time: 39},
            {longitude: 100.980228, dimension: 39.771246, height: 55, time: 40},
            {longitude: 100.980228, dimension: 39.771246, height: 60, time: 41},
            {longitude: 100.980228, dimension: 39.771246, height: 65, time: 42},
            {longitude: 100.980228, dimension: 39.771246, height: 70, time: 43},
            {longitude: 100.980228, dimension: 39.771246, height: 75, time: 44},
            {longitude: 100.980228, dimension: 39.771246, height: 80, time: 45},
            {longitude: 100.980228, dimension: 39.771246, height: 85, time: 46},
        ];

        // 起始时间
        let start = Cesium.JulianDate.fromDate(new Date(2019, 8, 19));
        // 结束时间
        let stop = Cesium.JulianDate.addSeconds(start, 90, new Cesium.JulianDate());
        // 设置始时钟始时间
        view.clock.startTime = start.clone();
        // 设置时钟当前时间
        view.clock.currentTime = start.clone();
        // 设置始终停止时间
        view.clock.stopTime = stop.clone();
        // 时间速率，数字越大时间过的越快
        view.clock.multiplier = 10;
        // 时间轴
        view.timeline.zoomTo(start, stop);
        // 循环执行,即为2，到达终止时间，重新从起点时间开始
        view.clock.clockRange = Cesium.ClockRange.LOOP_STOP;

        // // 镜头飞跃
        // view.camera.flyTo({
        //     destination:Cesium.Cartesian3.fromDegrees(116.405419,32.073514,500000)
        // })

        for (let j = 0; j < data.length; j++) {
            let property = computeFlight(data[j]);
            // 添加模型
            let planeModel = view.entities.add({
                // 和时间轴关联
                availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
                    start: start,
                    stop: stop
                })]),
                position: property,
                // 根据所提供的速度计算模型的朝向
                orientation: new Cesium.VelocityOrientationProperty(property),
                // 模型数据
                model: {
                    uri: 'model/testdaodan.gltf',
                }
            });
        }


        /**
         * 计算飞行
         * @param source 数据坐标
         * @returns {SampledPositionProperty|*}
         */
        function computeFlight(source) {
            // 取样位置 相当于一个集合
            let property = new Cesium.SampledPositionProperty();
            console.log("computeFlight property" + property)

            for (let i = 0; i < source.length; i++) {
                let time = Cesium.JulianDate.addSeconds(start, source[i].time, new Cesium.JulianDate);
                let position = Cesium.Cartesian3.fromDegrees(source[i].longitude, source[i].dimension, source[i].height);
                // 添加位置，和时间对应
                property.addSample(time, position);
            }
            return property;
        }

    }

    /**
     * 生成模型
     **/
    function createModel(url, id) {
        console.log("--->" + url);


        var position = Cesium.Cartesian3.fromDegrees($("#lng_none").val(), $("#lat_none").val(), $("#hig_none").val());

        // var position = Cesium.Cartesian3.fromDegrees(100.980302, 39.770788, 8);
        var heading = Cesium.Math.toRadians(135);
        var pitch = 0;
        var roll = 0;
        var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
        var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);

        var entity = viewer.entities.add({
            id: id,
            name: url,
            position: position,
            orientation: orientation,
            model: {
                uri: url,
            }
        });
        viewer.trackedEntity = entity;
    }

    /*
添加扫描线 depth关闭   lon:-74.01296152309055 lat:40.70524201566827 height:129.14366696393927
viewer
cartographicCenter 扫描中心
maxRadius 最大半径 米
scanColor 扫描颜色
duration 持续时间 毫秒
*/
    function AddCircleScanPostStage(viewer, cartographicCenter, maxRadius, scanColor, duration) {
        var ScanSegmentShader =
            "uniform sampler2D colorTexture;\n" +
            "uniform sampler2D depthTexture;\n" +
            "varying vec2 v_textureCoordinates;\n" +
            "uniform vec4 u_scanCenterEC;\n" +
            "uniform vec3 u_scanPlaneNormalEC;\n" +
            "uniform float u_radius;\n" +
            "uniform vec4 u_scanColor;\n" +
            "vec4 toEye(in vec2 uv, in float depth)\n" +
            " {\n" +
            " vec2 xy = vec2((uv.x * 2.0 - 1.0),(uv.y * 2.0 - 1.0));\n" +
            " vec4 posInCamera =czm_inverseProjection * vec4(xy, depth, 1.0);\n" +
            " posInCamera =posInCamera / posInCamera.w;\n" +
            " return posInCamera;\n" +
            " }\n" +
            "vec3 pointProjectOnPlane(in vec3 planeNormal, in vec3 planeOrigin, in vec3 point)\n" +
            "{\n" +
            "vec3 v01 = point -planeOrigin;\n" +
            "float d = dot(planeNormal, v01) ;\n" +
            "return (point - planeNormal * d);\n" +
            "}\n" +
            "float getDepth(in vec4 depth)\n" +
            "{\n" +
            "float z_window = czm_unpackDepth(depth);\n" +
            "z_window = czm_reverseLogDepth(z_window);\n" +
            "float n_range = czm_depthRange.near;\n" +
            "float f_range = czm_depthRange.far;\n" +
            "return (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n" +
            "}\n" +
            "void main()\n" +
            "{\n" +
            "gl_FragColor = texture2D(colorTexture, v_textureCoordinates);\n" +
            "float depth = getDepth( texture2D(depthTexture, v_textureCoordinates));\n" +
            "vec4 viewPos = toEye(v_textureCoordinates, depth);\n" +
            "vec3 prjOnPlane = pointProjectOnPlane(u_scanPlaneNormalEC.xyz, u_scanCenterEC.xyz, viewPos.xyz);\n" +
            "float dis = length(prjOnPlane.xyz - u_scanCenterEC.xyz);\n" +
            "if(dis < u_radius)\n" +
            "{\n" +
            "float f = 1.0 -abs(u_radius - dis) / u_radius;\n" +
            "f = pow(f, 4.0);\n" +
            "gl_FragColor = mix(gl_FragColor, u_scanColor, f);\n" +
            "}\n" +
            "}\n";
        var _Cartesian3Center = Cesium.Cartographic.toCartesian(cartographicCenter);
        var _Cartesian4Center = new Cesium.Cartesian4(_Cartesian3Center.x, _Cartesian3Center.y, _Cartesian3Center.z, 1);
        var _CartographicCenter1 = new Cesium.Cartographic(cartographicCenter.longitude, cartographicCenter.latitude, cartographicCenter.height + 500);
        var _Cartesian3Center1 = Cesium.Cartographic.toCartesian(_CartographicCenter1);
        var _Cartesian4Center1 = new Cesium.Cartesian4(_Cartesian3Center1.x, _Cartesian3Center1.y, _Cartesian3Center1.z, 1);
        var _time = (new Date()).getTime();
        var _scratchCartesian4Center = new Cesium.Cartesian4();
        var _scratchCartesian4Center1 = new Cesium.Cartesian4();
        var _scratchCartesian3Normal = new Cesium.Cartesian3();
        var ScanPostStage = new Cesium.PostProcessStage({
            fragmentShader: ScanSegmentShader,
            uniforms: {
                u_scanCenterEC: function () {
                    return Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center, _scratchCartesian4Center);
                },
                u_scanPlaneNormalEC: function () {
                    var temp = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center, _scratchCartesian4Center);
                    var temp1 = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center1, _scratchCartesian4Center1);
                    _scratchCartesian3Normal.x = temp1.x - temp.x;
                    _scratchCartesian3Normal.y = temp1.y - temp.y;
                    _scratchCartesian3Normal.z = temp1.z - temp.z;
                    Cesium.Cartesian3.normalize(_scratchCartesian3Normal, _scratchCartesian3Normal);
                    return _scratchCartesian3Normal;
                },
                u_radius: function () {
                    return maxRadius * (((new Date()).getTime() - _time) % duration) / duration;
                },
                u_scanColor: scanColor
            }
        });
        viewer.scene.postProcessStages.add(ScanPostStage);
    }


    /*-------------------------       ------------------------------------*/
    var trigger = $('.hamburger'),
        overlay = $('.overlay'),
        isClosed = false;

    trigger.click(function () {
        hamburger_cross();
    });


    function hamburger_cross() {

        if (isClosed == true) {
            overlay.hide();
            trigger.removeClass('is-open');
            trigger.addClass('is-closed');
            isClosed = false;
        } else {
            overlay.show();
            trigger.removeClass('is-closed');
            trigger.addClass('is-open');
            isClosed = true;
        }
    }

    $('[data-toggle="offcanvas"]').click(function () {
        $('#wrapper').toggleClass('toggled');
    });


    $(".quick_links_panel li").mouseenter(function () {
        $(this).children(".mp_tooltip").animate({left: -92, queue: true});
        $(this).children(".mp_tooltip").css("visibility", "visible");
        $(this).children(".ibar_login_box").css("display", "block");
    });

    $(".quick_links_panel li").mouseleave(function () {
        $(this).children(".mp_tooltip").css("visibility", "hidden");
        $(this).children(".mp_tooltip").animate({left: -121, queue: true});
        $(this).children(".ibar_login_box").css("display", "none");
    });

    $(".quick_toggle li").mouseover(function () {
        $(this).children(".mp_qrcode").show();
    });

    $(".quick_toggle li").mouseleave(function () {
        $(this).children(".mp_qrcode").hide();
    });


    // 元素以及其他一些变量

    var eleFlyElement = document.querySelector("#flyItem"), eleShopCart = document.querySelector("#shopCart");
    var numberItem = 0;
    // 抛物线运动
    var myParabola = funParabola(eleFlyElement, eleShopCart, {
        speed: 400, //抛物线速度
        curvature: 0.0008, //控制抛物线弧度
        complete: function () {
            eleFlyElement.style.visibility = "hidden";
            eleShopCart.querySelector("span").innerHTML = ++numberItem;
        }
    });

    // 绑定点击事件
    if (eleFlyElement && eleShopCart) {
        [].slice.call(document.getElementsByClassName("btnCart")).forEach(function (button) {
            button.addEventListener("click", function (event) {
                // 滚动大小
                var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft || 0,
                    scrollTop = document.documentElement.scrollTop || document.body.scrollTop || 0;
                eleFlyElement.style.left = event.clientX + scrollLeft + "px";
                eleFlyElement.style.top = event.clientY + scrollTop + "px";
                eleFlyElement.style.visibility = "visible";
                // 需要重定位
                myParabola.position().move();
            });
        });
    }
</script>

</body>
</html>
